#!/usr/bin/evn python
# -*-coding:utf-8 -*-

import inspect
import os
import pathlib
import time

import allure
import yaml
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.support.wait import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager

from ..conftest import global_env
from ..utils.log_util import logger


class BasePage:
    def __init__(self, base_driver: WebDriver = None):
        if base_driver is None:
            # # 初始化driver
            # server = Service(executable_path=ChromeDriverManager().install())
            # 1. 初始化 driver
            chrome_options = Options()
            chrome_options.add_argument('--headless')
            chrome_options.add_argument('--no-sandbox')  
            chrome_options.add_argument('--disable-gpu')
            chrome_options.add_argument('--disable-dev-shm-usage')
            self.driver = webdriver.Chrome(options=chrome_options)
            # 2. 隐式等待
            self.driver.implicitly_wait(10)
            # 3. 窗口最大化
            self.driver.maximize_window()
        else:
            self.driver = base_driver

        # 根据命令行指令获取到运行的环境，默认是test
        path_env = global_env.get("env")
        import pathlib
        file_path_tmp = pathlib.Path(__file__).parent.parent
        file_path = file_path_tmp / 'config/host.yaml'

        env = yaml.safe_load(open(file_path,
                                  encoding="utf-8"))
        self.base_url = env["base_url"][f"{path_env}"]
        self.driver.implicitly_wait(5)

    def open_url(self):
        '''
        打开某个 url
        :param url:
        :return:
        '''
        logger.info(f'打开的url是 {self.base_url}')
        self.driver.get(self.base_url)

    def close_browser(self):
        '''
        关闭浏览器
        :return:
        '''
        logger.info('关闭浏览器')
        self.driver.quit()

    def find_ele(self, by, value=None):
        '''
        定位单个元素
        :param by:
        :param value:
        :return:
        '''
        with allure.step('查找元素'):
            try:
                if value is None:
                    logger.info(f'定位单个元素,定位方式为{by}')
                    ele = self.driver.find_element(*by)
                else:
                    logger.info(f'定位单个元素,定位方式为{by},定位表达式为{value}')
                    ele = self.driver.find_element(by, value)
            except Exception as e:
                ele = None
                logger.info(f'单个元素没有找到{e}')
                # 截图
                self.screnn_image()
                # 保存 pagesource
                self.save_page_source()
        return ele

    def find_eles(self, by, value=None):
        '''
        定位多个元素
        :param by:
        :param value:
        :return:
        '''
        if value == None:
            logger.info(f'定位单个元素,定位方式为{by}')
            eles = self.driver.find_elements(*by)
        else:
            logger.info(f'定位单个元素,定位方式为{by},定位表达式为{value}')
            eles = self.driver.find_elements(by, value)
        return eles

    def wait_until(self, method, timeout=10):
        '''
        显示等待封装
        :param method: 等待的条件  官方 or 自定义
        :param timeout:
        :return:
        '''
        try:
            ele = WebDriverWait(self.driver, timeout).until(method)
        except Exception as e:
            ele = None
            # 截图
            self.screnn_image()
            # 保存 pagesource
            self.save_page_source()
        return ele

    def login_by_cookie(self):
        '''
        通过 cookie 登录
        :return:
        '''
        temp_path = pathlib.Path(__file__).parent.parent
        cookie_file_path = temp_path / 'datas/cookies.yml'
        # 读取 cookie 信息
        with open(cookie_file_path, 'r', encoding='utf-8') as f:
            new_cookies = yaml.safe_load(f)
            for cookie in new_cookies:
                self.driver.add_cookie(cookie)
        # 刷新页面
        logger.info("刷新页面，完成登录")
        self.driver.refresh()

    def get_path(self, path_name):
        '''
        获取绝对路径
        :param path_name:
        :return:
        '''
        # 获取当前文件的目录
        root_path = os.path.dirname(os.path.abspath(__file__))
        # 拼接当前要输出日志的路径
        log_path = os.sep.join([root_path, '..', path_name])
        return log_path

    def screnn_image(self):
        '''
        截图
        :return:
        '''
        # 截图命名
        now_time = time.strftime('%Y_%m_%d_%H_%M_%S')
        image_name = f'{now_time}.png'
        # 拼接图片路径
        img_path = pathlib.Path(__file__).parent.parent / f"images/{image_name}"
        # 截图
        self.driver.save_screenshot(img_path)
        # 添加截图到报告
        allure.attach.file(img_path,
                           name='查找元素异常截图',
                           attachment_type=allure.attachment_type.PNG)
        return img_path

    def save_page_source(self):
        '''
        页面源码
        :return:
        '''
        # 命名
        now_time = time.strftime('%Y_%m_%d_%H_%M_%S')
        pagesource_name = f'{now_time}.html'
        # 拼接源码路径
        pagesource_path = pathlib.Path(__file__).parent.parent / f'pagesource/{pagesource_name}.html'
        # 保存源码
        with open(pagesource_path, 'w', encoding='utf-8') as f:
            f.write(self.driver.page_source)
        # 添加源码到报告
        allure.attach.file(pagesource_path,
                           name='查找元素异常截图',
                           attachment_type=allure.attachment_type.TEXT)
        return pagesource_path
